package com.glut.campusrepair.config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import okhttp3.*;
import okhttp3.MediaType;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;

import java.io.IOException;
import java.util.Date;

/**
 * AI
 */
@Configuration // 表示这是一个配置类，用于定义 Spring 的 Bean
@Slf4j // 使用 Lombok 注解生成日志记录器
public class WenXinConfig {

    // 从配置文件中读取 API_KEY，用于请求 API 的身份验证
    @Value("${wenxin.apiKey}")
    public String API_KEY;

    // 从配置文件中读取 SECRET_KEY，用于请求 API 的身份验证
    @Value("${wenxin.secretKey}")
    public String SECRET_KEY;

    // 从配置文件中读取 ACCESS_TOKEN_URL，用于获取 Access Token（访问令牌） 的 URL
    @Value("${wenxin.accessTokenUrl}")
    public String ACCESS_TOKEN_URL;

    // 从配置文件中读取 ERNIE_Bot_4_0_URL，用于访问 ERNIE Bot API 的 URL
    @Value("${wenxin.ERNIE_Bot.URL}")
    public String ERNIE_Bot_4_0_URL;

    // 存储当前的 Access Token，初始化为空
    public String ACCESS_TOKEN = null;

    // 存储当前的 Refresh Token，初始化为空
    public String REFRESH_TOKEN = null;

    // 存储 Access Token 的创建时间
    public Date CREATE_TIME = null;

    // 存储 Access Token 的过期时间
    public Date EXPIRATION_TIME = null;

    /**
     * 获取 Access Token 的方法。
     * @return 返回当前的 Access Token。如果获取失败，则返回 null。
     */
    public synchronized String flushAccessToken(){
        // 检查 ACCESS_TOKEN 是否为空，以及是否过期
        if(ACCESS_TOKEN != null && EXPIRATION_TIME.getTime() > CREATE_TIME.getTime()) {
            return ACCESS_TOKEN; // 如果 Access Token 尚未过期，则直接返回
        }

        // 构造请求体，设置请求的内容和头部信息
        RequestBody body = RequestBody.create(MediaType.parse("application/json"),"");
        Request request = new Request.Builder()
                .url(ACCESS_TOKEN_URL + "?client_id=" + API_KEY + "&client_secret=" + SECRET_KEY + "&grant_type=client_credentials")
                .method("POST", body)
                .addHeader("Content-Type", "application/json")
                .addHeader("Accept", "application/json")
                .build();

        // 创建 OkHttpClient 实例 用于构建和配置 HTTP 客户端
        OkHttpClient HTTP_CLIENT = new OkHttpClient().newBuilder().build();

        String response = null;
        try {
            // 发送请求并获取响应
            response = HTTP_CLIENT.newCall(request).execute().body().string();
        } catch (IOException e) {
            // 如果请求过程中出现 IO 异常，记录错误日志并返回 null
            log.error("ACCESS_TOKEN获取失败");
            return null;
        }

        // 解析响应内容，刷新令牌以及更新令牌的创建时间和过期时间
        JSONObject jsonObject = JSON.parseObject(response); //从 HTTP 的响应内容中获取 JSON 格式的数据中提取信息
        ACCESS_TOKEN = jsonObject.getString("access_token");//获取令牌
        REFRESH_TOKEN = jsonObject.getString("refresh_token");//用于在 Access Token 过期后获取新的 Access Token
        CREATE_TIME = new Date(); // 设置令牌创建时间为当前时间
        EXPIRATION_TIME = new Date(Long.parseLong(jsonObject.getString("expires_in")) * 1000 + CREATE_TIME.getTime()); // 设置令牌过期时间

        return ACCESS_TOKEN; // 返回新获取的 Access Token
    }
}
